package com.skyworthclub.competition.service.impl;

import com.skyworthclub.competition.beans.Match;
import com.skyworthclub.competition.repository.MatchRepository;
import com.skyworthclub.competition.service.MatchElasticsearchService;
import com.skyworthclub.competition.utils.service.BeanUtil;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Optional;

/**
 * @author li
 * @version 1.0
 * @since 18-10-20 下午3:32
 **/
@Service
public class MatchElasticsearchServiceImpl implements MatchElasticsearchService {

    private final MatchRepository matchRepository;

    private static final Integer PAGE_SIZE = 5;

    @Autowired
    public MatchElasticsearchServiceImpl(MatchRepository matchRepository) {
        this.matchRepository = matchRepository;
    }


    @Override
    @Async
    public void save(Match match) {
        matchRepository.index(match);
    }


    @Override
    @Async
    public void delete(Integer matchId) {
        Match match = new Match();
        match.setMatchId(matchId);
        matchRepository.delete(match);
    }


    @Override
    @Async
    public void update(Match match) {
        Optional<Match> document = matchRepository.findById(match.getMatchId());
        if (!document.isPresent()) {
            return;
        }
        BeanUtil.transferValue(match, document);
        matchRepository.index(document.get());
    }


    @Override
    public Page<Match> matchQuery(String keyword, String field, Integer page) {
        Pageable pageable = PageRequest.of(page - 1, PAGE_SIZE);
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder(field, keyword);
        Page<Match> matchPage = matchRepository.search(matchQueryBuilder, pageable);
        return new PageImpl<>(matchPage.getContent(), pageable, matchPage.getTotalElements());
    }


    @Override
    public Page<Match> multiMatchQuery(String keyword, Integer page, String[] fields) {
        Sort sort = Sort.by("matchBeginTime", "matchId");
        Pageable pageable = PageRequest.of(page - 1, PAGE_SIZE, sort);
        //如果不指定搜索字段，则搜索如下四个
        if (fields == null || fields.length == 0) {
            fields = new String[]{"matchName", "matchSummary", "matchDetail", "matchOrganizer", "matchContestants"};
        }
        MultiMatchQueryBuilder searchQuery = new MultiMatchQueryBuilder(keyword, fields)
                .type(MultiMatchQueryBuilder.Type.PHRASE);
        Page<Match> matchPage = matchRepository.search(searchQuery, pageable);
        return new PageImpl<>(matchPage.getContent(), pageable, matchPage.getTotalElements());
    }

    @Override
    public Iterable<Match> multiMatchQuery(String keyword, String[] fields) {
        if (fields == null || fields.length == 0) {
            fields = new String[]{"matchName", "matchSummary", "matchDetail", "matchOrganizer", "matchContestants"};
        }
        MultiMatchQueryBuilder queryBuilder = new MultiMatchQueryBuilder(keyword, fields)
                .type(MultiMatchQueryBuilder.Type.PHRASE);
        return matchRepository.search(queryBuilder);
    }


    /**
     * 设定起始日期查询
     *
     * @param startDate 最早日期
     * @param endDate   最晚日期
     */
    public Page<Match> searchMatchesByRange(LocalDate startDate, LocalDate endDate, Integer pageNum) {
        //排序规则，默认为升序
        Sort sort = Sort.by("matchBeginTime", "matchId");
        //@param page zero-based page index.页数从零记起
        Pageable pageable = PageRequest.of(pageNum - 1, PAGE_SIZE, sort);
        RangeQueryBuilder queryBuilder = new RangeQueryBuilder("matchBeginTime")
                .from(startDate)
                .to(endDate);
        Page<Match> matchPage = matchRepository.search(queryBuilder, pageable);
        //将AggregatedPageImpl转换成PageImpl返回来排除以下异常
        // java.util.HashMap["matches"]->org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl["facets"])
        return new PageImpl<>(matchPage.getContent(), pageable, matchPage.getTotalElements());
    }

}
